package eclMain;

import java.util.ArrayList;

public class ChatLine {
	private String text = null; //the original string
	private String owner = null; //the person who said it
	private TimeStamp timeStamp = null;
	private String originalText = null;
	private Channel channel = null; //the channel where this line was said
	
	private final String CHANNELID = "channelid";
	private final String CHANNELIDTYPE = "channelidtype";
	private final String CHANNELNAME = "channelname";
	private final String CHANNELLISTENER = "channellistener";
	private final String CHANNELLOCATION = "channellocation";
	private final String LINEOWNER = "lineowner";
	private final String LINETEXT = "linetext";
	private final String TIMEYEAR = "timeyear";
	private final String TIMEMONTH = "timemonth";
	private final String TIMEDAY = "timeday";
	private final String TIMEHOUR = "timehour";
	private final String TIMEMINUTE = "timeminute";
	private final String TIMESECOND = "timesecond";
	
	private final String DELIMITER = ";;";
	
	/**Create a new ChatLine object. Passing in null,null will create a ChatLine object with null values for almost everything*/
	public ChatLine(String text, Channel channel) {
		if (text == null && channel == null) { //blank initialization
			this.channel = new Channel(null);
			this.timeStamp = new TimeStamp(null);
			return;
		}
		
		this.channel = channel;
		
		if (text.charAt(0) == (char)65279) {
			text = text.substring(1); //get rid of that irritating "echo" character
		}
		this.originalText = text;
		if (text.contains("]")) { //if it's a line of chat, and not a part of the header
			try {
				String rawTimestamp = text.substring(0, 24); //since the timestamp is always 24 characters long, i can do this
				String[] theRest = text.substring(24).split(">");
				
				rawTimestamp = rawTimestamp.replace('[', ' ').replace(']', ' ').trim(); //remove the brackets, and remove the extra whitespace
				this.timeStamp = new TimeStamp(rawTimestamp); //create timestamp object
				this.owner = theRest[0].trim();
				this.text = theRest[1].trim();
			} catch (Exception e) {
				this.text = null;
			}
		} else {
			this.text = text;
		}
	}
	
	
	public boolean equals(ChatLine chatLine) {
		if (this.getEntireLine().equals(chatLine.getEntireLine())) return true;
		return false;
	}
	
	public Channel getChannel() {
		return this.channel;
	}
	
	/**Returns the complete line as it looked when read*/
	public String getEntireLine() {
		return this.originalText;
	}
	
	/**Only returns the text string without the timestamp*/
	public String getText() {
		return this.text;
	}
	
	/**Returns the timestamp object*/
	public TimeStamp getTimeStamp() {
		return this.timeStamp;
	}
	
	/**Returns the character that typed this line*/
	public String getOwner() {
		return this.owner;
	}
	
	/**Returns the original input*/
	public String toString() {
		return this.originalText;
	}
	
	public String processOutput() {
		ArrayList<String> list = new ArrayList<String>();
    	list.add(CHANNELID + ":" + getChannel().getChannelID());
    	list.add(CHANNELIDTYPE + ":" + getChannel().getChannelIDType());
    	list.add(CHANNELNAME + ":" + getChannel().getChannelName());
    	list.add(CHANNELLISTENER + ":" + getChannel().getListener());
    	list.add(CHANNELLOCATION + ":" + getChannel().getLocation());
    	list.add(TIMEYEAR + ":" + getTimeStamp().getYear());
    	list.add(TIMEMONTH + ":" + getTimeStamp().getMonth());
    	list.add(TIMEDAY + ":" + getTimeStamp().getDate());
    	list.add(TIMEHOUR + ":" + getTimeStamp().getHour());
    	list.add(TIMEMINUTE + ":" + getTimeStamp().getMinute());
    	list.add(TIMESECOND + ":" + getTimeStamp().getSecond());
    	list.add(LINEOWNER + ":" + getOwner());
    	list.add(LINETEXT + ":" + getText()); //make sure that the text is always last, so that it doesn't mess up the parsers on the other end
    	String toReturn = "";
    	for (String s : list) {
    		toReturn += s + this.DELIMITER;
    	}
    	return toReturn;
	}
	
	public boolean processInput(String line) { //returns false if the pieceOfLine failed to find a place to put itself
		String[] piecesOfLine = line.split(this.DELIMITER);
		for (String pol : piecesOfLine) {
			String[] polSplit = pol.split(":");
			try {
				switch (polSplit[0]) {
					case CHANNELID: 
						getChannel().setChannelID(polSplit[1]);
						break;
					case CHANNELIDTYPE:
						getChannel().setChannelIDType(Integer.parseInt(polSplit[1]));
						break;
					case CHANNELNAME:
						getChannel().setChannelName(polSplit[1]);
						break;
					case CHANNELLISTENER:
						getChannel().setListener(polSplit[1]);
						break;
					case CHANNELLOCATION:
						getChannel().setLocation(polSplit[1]);
						break;
					case LINEOWNER:
						this.owner = polSplit[1];
						break;
					case LINETEXT:
						this.text = polSplit[1];
						break;
					case TIMEYEAR:
						getTimeStamp().setYear(Integer.parseInt(polSplit[1]));
						break;
					case TIMEMONTH:
						getTimeStamp().setMonth(Integer.parseInt(polSplit[1]));
						break;
					case TIMEDAY:
						getTimeStamp().setDate(Integer.parseInt(polSplit[1]));
						break;
					case TIMEHOUR:
						getTimeStamp().setHour(Integer.parseInt(polSplit[1]));
						break;
					case TIMEMINUTE:
						getTimeStamp().setMinute(Integer.parseInt(polSplit[1]));
						break;
					case TIMESECOND:
						getTimeStamp().setSecond(Integer.parseInt(polSplit[1]));
						break;
				} //end switch
			} catch (Exception e) {
				return false; //something failed to come over the wire; fail the line
			}
		}
		this.originalText = getTimeStamp().toString() + " " + getOwner() + " > " + getText();
		return checkIntegrity(); //return the state of the chatLine after parsing all the data
	}
	
	/**Checks to make sure that the class holds all the data that it is supposed to. These checks include relevant data within the ChatLine, Channel, and TimeStamp classes.
	 * Returns false if anything is out of place. Returns true if the check passed.*/
	public boolean checkIntegrity() {
		if (getChannel().getChannelID() == null) return false;
		if (getChannel().getChannelName() == null) return false;
		if (getChannel().getListener() == null) return false;
		if (getChannel().getLocation() == null) return false;
		if (getOwner() == null) return false;
		if (getText() == null) return false;
		if (getTimeStamp().getYear() == -1) return false;
		if (getTimeStamp().getMonth() == -1) return false;
		if (getTimeStamp().getDate() == -1) return false;
		if (getTimeStamp().getHour() == -1) return false;
		if (getTimeStamp().getMinute() == -1) return false;
		if (getTimeStamp().getSecond() == -1) return false;
		
		return true;
	}
}
